//! WebSocket使用示例
//! 
//! 展示如何使用WebSocket功能

use binance_sdk_unified::{
    client::BinanceClientBuilder, ProductType, Environment, Result,
};
// use binance_sdk_unified::websocket::WebSocketClient;
use std::time::Duration;
use tokio::time::sleep;
use serde_json;

#[tokio::main]
async fn main() -> Result<()> {
    // 初始化日志
    tracing_subscriber::fmt::init();

    // 从环境变量加载配置
    let api_key = std::env::var("BINANCE_API_KEY").unwrap_or_else(|_| "test_api_key".to_string());
    let secret_key = std::env::var("BINANCE_SECRET_KEY").unwrap_or_else(|_| "test_secret_key".to_string());
    
    // 解析环境 - 默认使用Live环境获取真实行情
    let environment = match std::env::var("BINANCE_ENVIRONMENT").unwrap_or_else(|_| "Live".to_string()).as_str() {
        "Live" => Environment::Live,
        "Demo" => Environment::Demo,
        _ => Environment::Live,  // 默认使用Live环境
    };
    
    // 解析超时和重试
    let timeout = std::env::var("BINANCE_TIMEOUT_SECONDS").unwrap_or_else(|_| "30".to_string()).parse::<u64>().unwrap_or(30);
    let retry_count = std::env::var("BINANCE_RETRY_COUNT").unwrap_or_else(|_| "3".to_string()).parse::<u32>().unwrap_or(3);
    
    println!("🚀 WebSocket多产品类型测试 - 真实行情数据");
    println!("=====================================");
    println!("💡 默认使用Live环境获取真实市场数据");
    println!("💡 可通过BINANCE_ENVIRONMENT环境变量控制");
    println!("💡 无需API密钥即可获取公共行情数据");
    println!("");
    
    // 测试配置 - 使用真实行情数据
    let test_cases = vec![
        ("现货交易", ProductType::Spot, "BTCUSDT"),
        ("USDT合约", ProductType::UsdM, "BTCUSDT"),
        ("币本位合约", ProductType::CoinM, "BTCUSD_PERP"),
    ];
    
    for (name, product_type, symbol) in test_cases {
        println!("\n🔧 测试 {} WebSocket连接", name);
        println!("   产品类型: {:?}", product_type);
        println!("   环境: {:?}", environment);
        println!("   交易对: {}", symbol);
        println!("   超时: {}秒", timeout);
        println!("   重试次数: {}次", retry_count);
        
        // 创建客户端
        let mut client = BinanceClientBuilder::new(
            api_key.clone(),
            secret_key.clone(),
            product_type,
        )
        .environment(environment)
        .timeout(timeout)
        .retry_count(retry_count)
        .build()?;

        // 获取WebSocket客户端
        let ws_client = client.websocket()?;

        // 连接WebSocket
        println!("🔌 正在连接WebSocket...");
        match ws_client.connect().await {
            Ok(_) => {
                println!("✅ {} WebSocket连接成功", name);
                
                // 订阅实时价格
                match ws_client.subscribe_ticker(symbol).await {
                    Ok(_) => println!("✅ 已订阅{}实时价格", symbol),
                    Err(e) => println!("❌ 订阅{}实时价格失败: {}", symbol, e),
                }

                // 订阅订单簿
                match ws_client.subscribe_depth(symbol, 20).await {
                    Ok(_) => println!("✅ 已订阅{}订单簿", symbol),
                    Err(e) => println!("❌ 订阅{}订单簿失败: {}", symbol, e),
                }

                // 订阅K线数据
                match ws_client.subscribe_kline(symbol, "1m").await {
                    Ok(_) => println!("✅ 已订阅{} 1分钟K线", symbol),
                    Err(e) => println!("❌ 订阅{} K线失败: {}", symbol, e),
                }

                // 等待一段时间让消息处理
                println!("📡 开始接收{} WebSocket消息...", name);
                println!("💡 请查看上方的日志输出，将显示实时行情数据");
                let mut message_count = 0;
                let max_messages = 15;  // 增加等待时间以获取更多数据

                while message_count < max_messages {
                    sleep(Duration::from_millis(1000)).await;
                    message_count += 1;
                    
                    if message_count % 5 == 0 {
                        println!("⏰ {} 等待消息中... ({}/{}) - 请查看上方日志获取实时数据", name, message_count, max_messages);
                    }
                }

                // 取消订阅
                match ws_client.unsubscribe(&format!("{}@ticker", symbol.to_lowercase())).await {
                    Ok(_) => println!("✅ 已取消订阅{}实时价格", symbol),
                    Err(e) => println!("❌ 取消订阅{}实时价格失败: {}", symbol, e),
                }

                // 关闭连接
                match ws_client.close().await {
                    Ok(_) => println!("✅ {} WebSocket连接已关闭", name),
                    Err(e) => println!("❌ 关闭{} WebSocket连接失败: {}", name, e),
                }
            },
            Err(e) => {
                println!("❌ {} WebSocket连接失败: {}", name, e);
            }
        }
        
        println!("-------------------------------------");
    }

    println!("\n🎉 所有WebSocket测试完成！");
    Ok(())
}

/// 用户数据流示例
async fn user_data_stream_example() -> Result<()> {
    let mut client = BinanceClientBuilder::new(
        "your_api_key".to_string(),
        "your_secret_key".to_string(),
        ProductType::Spot,
    )
    .environment(Environment::Demo)
    .build()?;

    // 启动用户数据流
    let listen_key = client.rest().account().start_user_data_stream().await?;
    println!("用户数据流监听密钥: {}", listen_key.listen_key);

    // 获取WebSocket客户端
    let ws_client = client.websocket()?;

    // 连接WebSocket
    ws_client.connect().await?;

    // 订阅用户数据流
    ws_client.subscribe_user_data(&listen_key.listen_key).await?;
    println!("已订阅用户数据流");

    // 处理用户数据流消息
    // 这里应该实现消息处理逻辑
    sleep(Duration::from_secs(5)).await;

    // 关闭WebSocket连接
    ws_client.close().await?;

    // 保持用户数据流活跃
    client.rest().account().keep_alive_user_data_stream(&listen_key.listen_key).await?;
    println!("用户数据流已保持活跃");

    // 关闭用户数据流
    client.rest().account().close_user_data_stream(&listen_key.listen_key).await?;
    println!("用户数据流已关闭");

    Ok(())
}

/// 流管理器示例
async fn stream_manager_example() -> Result<()> {
    use binance_sdk_unified::websocket::{StreamManager, StreamConfig};

    // 创建流管理器
    let mut manager = StreamManager::new();

    // 添加流配置
    let ticker_config = StreamConfig::ticker("BTCUSDT");
    let depth_config = StreamConfig::depth("BTCUSDT", 20);
    let kline_config = StreamConfig::kline("BTCUSDT", "1m");

    // 添加流到管理器
    let ticker_stream = manager.add_stream(ticker_config);
    let depth_stream = manager.add_stream(depth_config);
    let kline_stream = manager.add_stream(kline_config);

    println!("添加的流:");
    println!("- {}", ticker_stream);
    println!("- {}", depth_stream);
    println!("- {}", kline_stream);

    // 获取所有流
    let all_streams = manager.get_all_streams();
    println!("所有流: {:?}", all_streams);

    // 获取流配置
    if let Some(config) = manager.get_stream_config(&ticker_stream) {
        println!("Ticker流配置: {:?}", config);
    }

    // 移除流
    if let Some(removed_config) = manager.remove_stream(&ticker_stream) {
        println!("已移除流: {:?}", removed_config);
    }

    // 验证流名称
    use binance_sdk_unified::websocket::streams::StreamUtils;
    
    let valid_streams = [
        "btcusdt@ticker",
        "btcusdt@depth20",
        "btcusdt@kline_1m",
        "ethusdt@trade",
    ];

    for stream in &valid_streams {
        if StreamUtils::validate_stream_name(stream) {
            println!("流名称有效: {}", stream);
        } else {
            println!("流名称无效: {}", stream);
        }
    }

    // 解析流名称
    for stream in &valid_streams {
        match StreamUtils::parse_stream_name(stream) {
            Ok(config) => println!("解析成功: {} -> {:?}", stream, config),
            Err(e) => println!("解析失败: {} -> {}", stream, e),
        }
    }

    Ok(())
}

/// 错误处理示例
async fn error_handling_example() -> Result<()> {
    use binance_sdk_unified::errors::{BinanceError, error_codes};

    let client = BinanceClientBuilder::new(
        "invalid_api_key".to_string(),
        "invalid_secret_key".to_string(),
        ProductType::Spot,
    )
    .environment(Environment::Demo)
    .build()?;

    // 测试API错误处理
    match client.rest().get("/account", true).await {
        Ok(_) => println!("API调用成功"),
        Err(BinanceError::ApiError(api_err)) => {
            match api_err.code {
                error_codes::INVALID_API_KEY => println!("API密钥无效"),
                error_codes::INVALID_SIGNATURE => println!("签名验证失败"),
                error_codes::TOO_MANY_REQUESTS => println!("请求过于频繁"),
                _ => println!("API错误: {} - {}", api_err.code, api_err.msg),
            }
        }
        Err(BinanceError::NetworkError(msg)) => {
            println!("网络错误: {}", msg);
        }
        Err(e) => {
            println!("其他错误: {}", e);
        }
    }

    Ok(())
}
